package com.lzy.cloud.order.facade;

import com.lzy.cloud.order.constants.CommonConstants;
import com.lzy.cloud.order.dtos.*;
import com.lzy.cloud.order.remote.*;
import com.lzy.cloud.order.remote.dtos.AccountWalletDto;
import com.lzy.cloud.order.remote.dtos.BaseCouponDto;
import com.lzy.cloud.order.remote.dtos.CarCalendarDto;
import com.lzy.cloud.order.remote.dtos.ShopDto;
import com.lzy.cloud.order.service.*;
import com.lzy.cloud.order.service.impl.SerialNumberServiceImpl;
import com.lzy.cloud.order.strategy.CarRentOrderImpl;
import com.lzy.cloud.order.strategy.CarSaleOrderImpl;
import com.lzy.cloud.order.strategy.StrategyOrderContext;
import com.lzy.framework.core.ensure.Ensure;
import com.lzy.framework.core.output.Result;
import com.lzy.framework.core.utils.DozerUtils;
import com.lzy.framework.tools.date.DateStyle;
import com.lzy.framework.tools.date.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 订单总表
 * Created by WIN7 on 2018/6/6.
 */
@Component
@Slf4j
public class OrderInfoFacade {

    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private OrderInfoCarRentService orderInfoCarRentService;
    @Autowired
    private SerialNumberServiceImpl serialNumberServiceImpl;
    @Autowired
    private CarRentOrderImpl carRentOrderImpl;
    @Autowired
    private CarSaleOrderImpl carSaleOrderImpl;
    @Autowired
    private OrderStatusHistoryService orderStatusHistoryService;
    @Autowired
    private AccountWalletApi accountWalletApi;
    @Autowired
    private ShopApi shopApi;
    @Autowired
    private CouponApi couponApi;
    @Autowired
    private CarCalendarApi carCalendarApi;
    @Autowired
    private RabbitmqApi rabbitmqApi;
    @Autowired
    private OrderExpenseItemService orderExpenseItemService;
    @Autowired
    private OrderCouponLogService orderCouponLogService;


    /**
     * 方法说明：新增订单公共方法路由
     * @param    dto 订单基础信息
     * @return     订单支付信息
     * @date        2018/7/9 10:02
     */
    public BaseOrderDto createOrder(BaseOrderDto dto) {
        Ensure.that(dto).isNotNull("00000002");

        StrategyOrderContext soc = new StrategyOrderContext();
        if (soc == null) {
            return null;
        }

        BaseOrderDto resultDto = null;

        // 订单来源
        if (null == dto.getSource()) {
            dto.setSource(0);
        }

        // 调用api查询余额
        AccountWalletDto accountWalletDto = new AccountWalletDto();
        accountWalletDto.setMemberId(dto.getMemberId());
        Result result = accountWalletApi.findById(accountWalletDto);
        List<AccountWalletDto> awDtoList = DozerUtils.maps((List)result.getResult(), AccountWalletDto.class);
        Ensure.that(awDtoList).isNotNull("00000003");
        // 余额直接提现部分
        BigDecimal directAmount = new BigDecimal(0);
        for (AccountWalletDto awDto: awDtoList) {
            if (awDto.getType() == 2) {
                directAmount = awDto.getBalance();
            }
        }
        dto.setDirectAmount(directAmount);

        // 订单编号生成
        String orderId = serialNumberServiceImpl.createSerialNumber(dto.getType() + "", dto.getMemberId() + "") + "";
//        String orderId = DateUtils.DateToString(null, DateStyle.YYYYMMDDHHMM);
        dto.setOrderId(orderId);

        // 支付截止时间
        dto.setStopPayTime(DateUtils.DateToString(DateUtils.addMinutes(
                new Date(), CommonConstants.ADD_STOP_PAY_TIME),DateStyle.YYYY_MM_DD_HH_MM_SS));

        // 查询商户和平台名称
        Result shopResult = shopApi.selectById(dto.getShopId());
        ShopDto shopDto = DozerUtils.map(shopResult.getResult(), ShopDto.class);
        Ensure.that(shopDto).isNotNull("00000003");
        Result platFormResult = shopApi.selectById(dto.getPlatformId());
        ShopDto platFormDto = DozerUtils.map(platFormResult.getResult(), ShopDto.class);
        Ensure.that(platFormDto).isNotNull("00000003");
        dto.setShopName(shopDto.getName());
        dto.setPlatformName(platFormDto.getName());

        switch (dto.getType() + "") {
            // 房车销售
            case CommonConstants.Biz.TOUR_CAR_SALE: {
                soc.setCommonsOrder(carSaleOrderImpl);
                resultDto = soc.createOrder(dto);
                break;
            }
            // 房车租赁
            case CommonConstants.Biz.TOUR_CAR_RENT: {
                soc.setCommonsOrder(carRentOrderImpl);
                resultDto = soc.createOrder(dto);
                break;
            }
            default: {
                Ensure.that(true).isFalse("08000001");
                break;
            }
        }
        // TODO 调试时取消 30分钟后关闭订单
//        rabbitmqApi.cancelOrder(dto.getOrderId());

        return resultDto;
    }

    /**
     *  确认支付
     *
     * @param dto
     * @return
     */
    public PayOrderMoneyDto confirmPay(BaseOrderDto dto) {
        StrategyOrderContext soc = new StrategyOrderContext();
        if (soc == null) {
            return null;
        }

        PayOrderMoneyDto payDto = null;

        // 开启余额支付
        if (dto.getBalanceType().equals(1)) {
            // 调用api查询余额
            AccountWalletDto accountWalletDto = new AccountWalletDto();
            accountWalletDto.setMemberId(dto.getMemberId());
            Result result = accountWalletApi.findById(accountWalletDto);
            List<AccountWalletDto> awDtoList = DozerUtils.maps((List)result.getResult(), AccountWalletDto.class);
            Ensure.that(awDtoList).isNotNull("00000003");
            // 余额直接提现部分
            BigDecimal directAmount = new BigDecimal(0);
            for (AccountWalletDto awDto: awDtoList) {
                if (awDto.getType() == 2) {
                    directAmount = awDto.getBalance();
                }
            }
            dto.setDirectAmount(directAmount);
        }

        switch (dto.getType()+"") {
            // 房车销售
            case CommonConstants.Biz.TOUR_CAR_SALE: {
                soc.setCommonsOrder(carSaleOrderImpl);
                payDto = soc.confirmPay(dto);
                break;
            }
            // 房车租赁
            case CommonConstants.Biz.TOUR_CAR_RENT: {
                soc.setCommonsOrder(carRentOrderImpl);
                payDto = soc.confirmPay(dto);
                break;
            }
            default: {
                Ensure.that(true).isFalse("08000001");
                break;
            }
        }
        return payDto;
    }

    /**
     *  取消支付
     *
     * @param orderId
     * @return
     */
    public boolean cancelPay(String orderId) {
        OrderInfoDto orderInfoDto = orderInfoService.find(orderId);
        Long memberId = orderInfoDto.getMemberId();
        Long platformId = orderInfoDto.getPlatformId();

        switch (orderInfoDto.getType()+"") {
            // 房车销售
            case CommonConstants.Biz.TOUR_CAR_SALE: {
                // 1.余额冻结释放
                // 查询余额
                OrderExpenseItemDto searchDto = new OrderExpenseItemDto();
                searchDto.setOrderId(orderId);
                searchDto.setType(CommonConstants.OrderExpenseItemType.DIRECT_AMOUNT);
                List<OrderExpenseItemDto> searchList = orderExpenseItemService.queryList(searchDto);
                if (searchList.size() > 0) {
                    // 调用钱包api余额
                    AccountWalletDto accountWalletDto = new AccountWalletDto();
                    accountWalletDto.setBalance(searchList.get(0).getAmount());
                    accountWalletDto.setMemberId(memberId);
                    accountWalletDto.setPlatformId(platformId);
                    boolean accountResult = (Boolean)accountWalletApi.frozenAmountBecomeBalance(accountWalletDto).getResult();
                    Ensure.that(accountResult).isTrue("01000001");
                }

                break;
            }
            // 房车租赁
            case CommonConstants.Biz.TOUR_CAR_RENT: {
                // 1.余额冻结释放
                // 查询余额
                OrderExpenseItemDto searchDto = new OrderExpenseItemDto();
                searchDto.setOrderId(orderId);
                searchDto.setType(CommonConstants.OrderExpenseItemType.DIRECT_AMOUNT);
                List<OrderExpenseItemDto> searchList = orderExpenseItemService.queryList(searchDto);
                if (searchList.size() > 0) {
                    // 调用钱包api余额
                    AccountWalletDto accountWalletDto = new AccountWalletDto();
                    accountWalletDto.setBalance(searchList.get(0).getAmount());
                    accountWalletDto.setMemberId(memberId);
                    accountWalletDto.setPlatformId(platformId);
                    boolean accountResult = (Boolean)accountWalletApi.frozenAmountBecomeBalance(accountWalletDto).getResult();
                    Ensure.that(accountResult).isTrue("01000001");
                }

                // 2.卡券释放
                List<OrderCouponLogDto> list = orderCouponLogService.queryListByOrderId(orderId);
                for (int i = 0; i < list.size(); i++) {
                    // 订单卡券记录删除
                    OrderCouponLogDto orderCouponLogDto = list.get(i);
                    orderCouponLogService.delete(orderCouponLogDto.getId());

                    // 卡券锁定释放
                    BaseCouponDto baseCouponDto = new BaseCouponDto();
                    baseCouponDto.setId(orderCouponLogDto.getCouponId());
                    baseCouponDto.setLocked(false);
                    couponApi.update(baseCouponDto).getResult();
                }

                break;
            }
            default: {
                Ensure.that(true).isFalse("08000001");
                break;
            }
        }

        return true;
    }

    /**
     * 更新订单
     *
     * @param dto
     * @return
     */
    public Boolean update(BaseOrderDto dto) {
        // 订单修改
        OrderInfoDto orderInfoDto = DozerUtils.map(dto, OrderInfoDto.class);
        Ensure.that(orderInfoService.update(orderInfoDto)).isTrue("");

        // 订单状态变化记录
        OrderStatusHistoryDto orderStatusHistoryDto = new OrderStatusHistoryDto();
        orderStatusHistoryDto.setOrderId(dto.getOrderId());
        orderStatusHistoryDto.setStatus(dto.getMinStatus());
        orderStatusHistoryDto.setDesStatus(dto.getDesStatus());
        orderStatusHistoryDto.setOperateId(dto.getUpdateUser());
        OrderInfoDto orderInfoDto1 = orderInfoService.find(dto.getOrderId());
        if (CommonConstants.DEFAULT_TIME.equals(orderInfoDto1.getPayTime())) {
            orderStatusHistoryDto.setPayStatus(CommonConstants.OrderStatusHistoryPayStatus.NO);
        } else {
            orderStatusHistoryDto.setPayStatus(CommonConstants.OrderStatusHistoryPayStatus.YES);
        }
        // TODO 发货状态判断
//        orderStatusHistoryDto.setGoodStatus();
        orderStatusHistoryDto.setOperateName(dto.getOperateName());
        orderStatusHistoryDto.setOperateType(dto.getOperateType());
        orderStatusHistoryService.create(orderStatusHistoryDto);

        boolean result = true;
         switch (orderInfoDto1.getType()+"") {
            // 房车销售
            case CommonConstants.Biz.TOUR_CAR_SALE: {

                break;
            }
            // 房车租赁
            case CommonConstants.Biz.TOUR_CAR_RENT: {
                OrderInfoCarRentDto orderInfoCarRentDto = new OrderInfoCarRentDto();
                orderInfoCarRentDto.setOrderId(orderInfoDto.getOrderId());
                orderInfoCarRentDto.setCarStatus(orderInfoDto.getCarStatus());
                orderInfoCarRentDto.setUpdateUser(orderInfoDto.getUpdateUser());
                result = orderInfoCarRentService.update(orderInfoCarRentDto);
                break;
            }
            default: {
                Ensure.that(true).isFalse("08000001");
                break;
            }
        }

        return result;
    }

    /**
     * 方法说明：根据订单号查找订单
     * @param   orderId
     * @return
     * @date        2018/7/10 10:37
     */
    public BaseOrderDto find(String orderId){
        Ensure.that(orderId).isNotNull("00000002");
        StrategyOrderContext soc = new StrategyOrderContext();
        OrderInfoDto orderInfoDto = orderInfoService.find(orderId);
        Ensure.that(orderInfoDto).isNotNull("00010007");
        BaseOrderDto dto = null;

        switch (orderInfoDto.getType()+"") {
            // 房车销售
            case CommonConstants.Biz.TOUR_CAR_SALE: {
                soc.setCommonsOrder(carSaleOrderImpl);
                dto = soc.selectOrderByOrderId(orderId);
                break;
            }
            // 房车租赁
            case CommonConstants.Biz.TOUR_CAR_RENT: {
                soc.setCommonsOrder(carRentOrderImpl);
                dto = soc.selectOrderByOrderId(orderId);
                break;
            }
            default: {
                Ensure.that(true).isFalse("08000001");
                break;
            }
        }
        return dto;
    }

    /**
     * 取消订单
     *
     * @param dto
     * @return
     */
    public Boolean cancel(BaseOrderDto dto) {
        // 判断订单状态
        OrderInfoDto orderDto = orderInfoService.find(dto.getOrderId());
        if (orderDto.getMaxStatus() != CommonConstants.OrderBigStatus.NO_PAY_ORDER) {
            // 已支付订单不能取消
            return false;
        }

        // 余额和卡券释放
        cancelPay(dto.getOrderId());

        // 档期释放
        OrderInfoCarRentDto orderInfoCarRentDto = orderInfoCarRentService.queryByOrderId(dto.getOrderId());
        CarCalendarDto carCalendarDto = new CarCalendarDto();
        carCalendarDto.setCarId(orderInfoCarRentDto.getCarId());
        carCalendarDto.setStartDate(orderInfoCarRentDto.getStartDate());
        carCalendarDto.setEndDate(orderInfoCarRentDto.getEndDate());
        Ensure.that(DozerUtils.map(carCalendarApi.releaseCalendar(carCalendarDto).getResult(), Boolean.class)).isTrue("01000006");

        // 修改订单状态
        OrderInfoDto orderInfoDto = DozerUtils.map(dto, OrderInfoDto.class);
        orderInfoDto.setMaxStatus(CommonConstants.OrderBigStatus.OVER_ORDER);
        orderInfoDto.setMinStatus(4);
        Ensure.that(orderInfoService.update(orderInfoDto)).isTrue("");

        // 订单状态变化记录
        OrderStatusHistoryDto orderStatusHistoryDto = new OrderStatusHistoryDto();
        orderStatusHistoryDto.setOrderId(dto.getOrderId());
        orderStatusHistoryDto.setStatus(4);
        orderStatusHistoryDto.setDesStatus(dto.getDesStatus());
        OrderInfoDto orderInfoDto1 = orderInfoService.find(dto.getOrderId());
        if (CommonConstants.DEFAULT_TIME.equals(orderInfoDto1.getPayTime())) {
            orderStatusHistoryDto.setPayStatus(CommonConstants.OrderStatusHistoryPayStatus.NO);
        } else {
            orderStatusHistoryDto.setPayStatus(CommonConstants.OrderStatusHistoryPayStatus.YES);
        }
        // TODO 发货状态判断
//        orderStatusHistoryDto.setGoodStatus();
        orderStatusHistoryDto.setOperateId(dto.getUpdateUser());
        orderStatusHistoryDto.setOperateType(dto.getOperateType());
        orderStatusHistoryDto.setOperateName(dto.getOperateName());
        orderStatusHistoryService.create(orderStatusHistoryDto);

        return true;
    }
}
